home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 130_01 / scn.lib < prev    next >
Text File  |  1985-03-09  |  3KB  |  117 lines

  1. /*
  2.     General formatted input conversion routine. "line" points
  3.     to a string containing ascii text to be converted, and "fmt"
  4.     points to an argument list consisting of first a format
  5.     string and then a list of pointers to the destination objects.
  6.  
  7.     Appropriate data is picked up from the text string and stored
  8.     where the pointer arguments point according to the format string.
  9.     See K&R for more info. The field width specification is not
  10.     supported by this version.
  11.  
  12.     NOTE: the "%s" termination character has been changed
  13.     from "any white space" to the character following the "%s"
  14.     specification in the format string. That is, the call
  15.  
  16.         sscanf(string, "%s:", &str);
  17.  
  18.     would ignore leading white space (as is the case with all
  19.     format conversions), and then read in ALL subsequent text
  20.     (including newlines) into the buffer "str" until a COLON
  21.     or null byte is encountered.
  22.  
  23.     Returns the number of tokens assigned from the source line
  24.     (a number from 0 to <number of control string conversions,
  25.     or '%'s>), unassigned elements are set to 0 (including strings).
  26. */
  27.  
  28. int _scn(line,fmt)
  29. char *line, **fmt;
  30. {
  31.     char eolf, sf, c, base, n, *sptr, *format;
  32.     int sign, val, **args;
  33.  
  34.     format = *fmt++;    /* fmt first points to the format string */
  35.     args = fmt;        /* now it points to the arg list */
  36.  
  37.     n = eolf = 0;
  38.     while (c = *format++) {
  39.        if (!*line) eolf = 1;    /* end of input string */
  40.        if (isspace(c)) continue;    /* skip white space in format string */
  41.        if (c != '%') {        /* if not %, must match text */
  42.         if (c != _igs(&line)) eolf = 1;
  43.         else line++;
  44.         }
  45.        else {            /* process conversion */
  46.         sign = 1;
  47.         base = 10;
  48.         val = sf = 0;
  49.         if ((c = *format++) == '*') {
  50.             sf++;        /* if "*" given, supress assignment */
  51.             c = *format++;
  52.          }
  53.         switch (toupper(c)) {
  54.            case 'X': base = 16;
  55.                  goto doval;
  56.  
  57.            case 'O': base = 8;
  58.                  goto doval;
  59.  
  60.            case 'D': if (eolf) break;
  61.                  if (_igs(&line) == '-') {
  62.                 sign = -1;
  63.                 line++;
  64.                   }
  65.  
  66.        doval:  case 'U': if (eolf) break;
  67.                  if (_bc(_igs(&line),base) == ERROR) {
  68.                 eolf = 1;
  69.                 break;
  70.                  }
  71.                  while ((c = _bc(*line++,base)) != 255)
  72.                 val = val * base + c;
  73.                  line--;
  74.                  break;
  75.  
  76.            case 'S': sptr = *args;
  77.                  if (!sf) *sptr = '\0';
  78.                  if (eolf) {
  79.            skiparg:    if (!sf) ++args;
  80.                 continue;
  81.                  }
  82.                  _igs(&line);
  83.                  while (c = *line++)   {
  84.                 if (c == *format) {
  85.                     format++;
  86.                     break;
  87.                  }
  88.                 if (!sf) *sptr++ = c;
  89.                   }                
  90.                  if (!c) --line; /* point to end of string */
  91.                  if (!sf) {
  92.                 n++;
  93.                 *sptr = '\0';
  94.                 args++;
  95.                   }
  96.                  continue;
  97.  
  98.            case 'C': if (!sf) poke(*args, '\0');
  99.                  if (eolf) goto skiparg;
  100.                  if (!sf) {
  101.                 poke(*args++, *line);
  102.                 n++;
  103.                  }
  104.                  line++;
  105.                  continue;
  106.  
  107.            default:  eolf = 1;
  108.                  continue;
  109.          }
  110.         if (!sf) {
  111.             **args++ = val * sign;
  112.             if (!eolf) n++;
  113.          }
  114.     }}
  115.     return n;
  116. }
  117.